/**
 * Validation utilities for the Emotion 3D Website
 * Requirements: 3.3, 3.4, 6.2, 6.3
 */

import type { EmotionReport, EmotionItem } from '../types';

/**
 * Validates that an EmotionItem has the required structure
 */
export function isValidEmotionItem(item: unknown): item is EmotionItem {
  if (typeof item !== 'object' || item === null) {
    return false;
  }
  
  const obj = item as Record<string, unknown>;
  
  return (
    typeof obj.name === 'string' &&
    obj.name.length > 0 &&
    typeof obj.intensity === 'number' &&
    obj.intensity >= 0 &&
    obj.intensity <= 100 &&
    typeof obj.color === 'string' &&
    obj.color.length > 0 &&
    typeof obj.icon === 'string'
  );
}

/**
 * Validates that an EmotionReport has the complete required structure
 * Property 6: Emotion Report Structure Completeness
 */
export function isValidEmotionReport(report: unknown): report is EmotionReport {
  if (typeof report !== 'object' || report === null) {
    return false;
  }
  
  const obj = report as Record<string, unknown>;
  
  // Check emotions array exists and is non-empty
  if (!Array.isArray(obj.emotions) || obj.emotions.length === 0) {
    return false;
  }
  
  // Validate each emotion item
  if (!obj.emotions.every(isValidEmotionItem)) {
    return false;
  }
  
  // Check suggestions array exists and is non-empty
  if (!Array.isArray(obj.suggestions) || obj.suggestions.length === 0) {
    return false;
  }
  
  // Validate suggestions are strings
  if (!obj.suggestions.every((s: unknown) => typeof s === 'string')) {
    return false;
  }
  
  // Check summary is a string
  if (typeof obj.summary !== 'string') {
    return false;
  }
  
  // Check timestamp exists (can be Date or string)
  if (!(obj.timestamp instanceof Date) && typeof obj.timestamp !== 'string') {
    return false;
  }
  
  return true;
}


// ============================================
// Input Sanitization - Requirements 6.2
// ============================================

/**
 * Dangerous patterns that should be sanitized from user input
 */
const DANGEROUS_PATTERNS = [
  /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, // Script tags
  /<[^>]*on\w+\s*=/gi, // Event handlers (onclick, onerror, etc.)
  /javascript:/gi, // JavaScript protocol
  /data:/gi, // Data protocol
  /vbscript:/gi, // VBScript protocol
];

/**
 * SQL injection patterns to detect
 */
const SQL_INJECTION_PATTERNS = [
  /(\b(SELECT|INSERT|UPDATE|DELETE|DROP|UNION|ALTER|CREATE|TRUNCATE)\b)/gi,
  /(--)|(;)|(\/\*)|(\*\/)/g, // SQL comments and statement terminators
  /(\bOR\b|\bAND\b)\s*\d+\s*=\s*\d+/gi, // OR 1=1, AND 1=1 patterns
];

/**
 * Sanitizes user input by escaping or removing dangerous characters
 * Property 10: Input Sanitization
 * Requirements: 6.2
 * 
 * @param input - Raw user input string
 * @returns Sanitized string safe for API transmission
 */
export function sanitizeInput(input: string): string {
  if (typeof input !== 'string') {
    return '';
  }

  let sanitized = input;

  // Remove script tags and their content
  for (const pattern of DANGEROUS_PATTERNS) {
    sanitized = sanitized.replace(pattern, '');
  }

  // Escape HTML entities
  sanitized = sanitized
    .replace(/&/g, '&amp;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;')
    .replace(/"/g, '&quot;')
    .replace(/'/g, '&#x27;');

  // Remove SQL injection patterns (replace with empty string)
  for (const pattern of SQL_INJECTION_PATTERNS) {
    sanitized = sanitized.replace(pattern, '');
  }

  return sanitized.trim();
}

/**
 * Checks if input contains potentially dangerous content
 * 
 * @param input - Raw user input string
 * @returns true if dangerous content is detected
 */
export function containsDangerousContent(input: string): boolean {
  if (typeof input !== 'string') {
    return false;
  }

  for (const pattern of DANGEROUS_PATTERNS) {
    if (pattern.test(input)) {
      return true;
    }
  }

  for (const pattern of SQL_INJECTION_PATTERNS) {
    if (pattern.test(input)) {
      return true;
    }
  }

  return false;
}

// ============================================
// API Response Validation - Requirements 6.3
// ============================================

/**
 * Validates the structure of an AnalyzeEmotionResponse
 * Property 11: Response Validation
 * Requirements: 6.3
 */
export function isValidAnalyzeEmotionResponse(response: unknown): boolean {
  if (typeof response !== 'object' || response === null) {
    return false;
  }

  const obj = response as Record<string, unknown>;

  // Check required fields
  if (typeof obj.success !== 'boolean') {
    return false;
  }

  // If success is true, report and imagePrompt are required
  if (obj.success === true) {
    if (!isValidEmotionReport(obj.report)) {
      return false;
    }
    if (typeof obj.imagePrompt !== 'string') {
      return false;
    }
  }

  // If success is false, error should be present
  if (obj.success === false) {
    if (typeof obj.error !== 'string') {
      return false;
    }
  }

  return true;
}

/**
 * Validates the structure of a GenerateImageResponse
 * Property 11: Response Validation
 * Requirements: 6.3
 */
export function isValidGenerateImageResponse(response: unknown): boolean {
  if (typeof response !== 'object' || response === null) {
    return false;
  }

  const obj = response as Record<string, unknown>;

  // Check required fields
  if (typeof obj.success !== 'boolean') {
    return false;
  }

  // If success is true, imageUrl is required
  if (obj.success === true) {
    if (typeof obj.imageUrl !== 'string' || obj.imageUrl.length === 0) {
      return false;
    }
  }

  // If success is false, error should be present
  if (obj.success === false) {
    if (typeof obj.error !== 'string') {
      return false;
    }
  }

  return true;
}
